﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Activation;
using AteneoLibriBusinessLogic.Entities;
using AteneoLibri.MyException.ServiceException;

namespace AteneoLibri.AteneoLibriServices
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "AteneoLibriService" in code, svc and config file together.
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class AteneoLibriService : IAteneoLibriService
    {

        AteneoLibriBusinessLogic.DAL.UniversityFacade universityFacade = new AteneoLibriBusinessLogic.DAL.UniversityFacade();
        AteneoLibriBusinessLogic.DAL.UserFacade userFacade = new AteneoLibriBusinessLogic.DAL.UserFacade();
        AteneoLibriBusinessLogic.DAL.FacultyFacade facultyFacade = new AteneoLibriBusinessLogic.DAL.FacultyFacade();
        AteneoLibriBusinessLogic.DAL.BookFacade bookFacade = new AteneoLibriBusinessLogic.DAL.BookFacade();
        AteneoLibriBusinessLogic.DAL.RecoveryCodeFacade recoveryFacade = new AteneoLibriBusinessLogic.DAL.RecoveryCodeFacade();
        AteneoLibriBusinessLogic.DAL.MessageFacade messageFacade = new AteneoLibriBusinessLogic.DAL.MessageFacade();
        AteneoLibriBusinessLogic.DAL.SaleFacade saleFacade = new AteneoLibriBusinessLogic.DAL.SaleFacade();
        AteneoLibriBusinessLogic.DAL.NationFacade nationFacade = new AteneoLibriBusinessLogic.DAL.NationFacade();
        AteneoLibriBusinessLogic.DAL.CityFacade cityFacade = new AteneoLibriBusinessLogic.DAL.CityFacade();

        #region Nation

        public List<Nation> getNations()
        {
            List<Nation> nations = nationFacade.getNations();
            return nations;
        }

        public bool insertNation(Nation nation)
        {
            bool result = false;
            try
            {
                result = nationFacade.insertNation(nation);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool updateNation(Nation nation)
        {
            bool result = false;
            try
            {
                result = nationFacade.updateNation(nation);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public Nation getNation(Guid nationId)
        {
            Nation nation = nationFacade.getNation(nationId);
            return nation;
        }

        public bool deleteNation(Nation nation)
        {
            bool result = false;
            try
            {
                result = nationFacade.deleteNation(nation);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        #endregion

        #region City

        public List<City> getCities()
        {
            List<City> cities = cityFacade.getCities();
            return cities;
        }

        public City getCity(Guid cityId)
        {
            City city = cityFacade.getCity(cityId);
            return city;
        }

        public List<City> getCitiesByNationId(Guid nationId)
        {
            List<City> cities = cityFacade.getCitiesByNationId(nationId);
            return cities;
        }

        public bool insertCity(City city)
        {
            bool result = false;
            try
            {
                result = cityFacade.insertCity(city);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool updateCity(City city)
        {
            bool result = false;
            try
            {
                result = cityFacade.updateCity(city);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public bool deleteCity(City city)
        {
            bool result = false;
            try
            {
                result = cityFacade.deleteCity(city);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        #endregion

        #region University

        public List<University> getUniversities()
        {
            IEnumerable<University> universities = new List<University>();
            universities = universityFacade.getUniversities();
            return universities.ToList();
        }

        public University getUniversity(Guid idUniversity)
        {
            University university = universityFacade.getUniversity(idUniversity);
            return university;
        }

        public List<University> getUniversityByCityId(Guid cityId)
        {
            List<University> universities = universityFacade.getUniversityByCityId(cityId);
            return universities;
        }

        public bool insertUniversity(University university)
        {
            bool result = false;
            try
            {
                result = universityFacade.insertUniversity(university);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool updateUniversity(University university)
        {
            bool result = false;
            try
            {
                result = universityFacade.updateUniversity(university);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public bool deleteUniversity(University university)
        {
            bool result = false;
            try
            {
                result = universityFacade.deleteUniversity(university);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        #endregion

        #region Faculty
        public List<Faculty> getFacultiesByUniversity(Guid universityId)
        {
            List<Faculty> faculties = facultyFacade.getFaculties(universityId);
            return faculties;
        }

        public Faculty getFaculty(Guid idFaculty)
        {
            Faculty faculty = facultyFacade.getFaculty(idFaculty);
            return faculty;
        }

        public bool insertFaculty(Faculty faculty)
        {
            bool result = false;
            try
            {
                result = facultyFacade.insertFaculty(faculty);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool updateFaculty(Faculty faculty)
        {
            bool result = false;
            try
            {
                result = facultyFacade.updateFaculty(faculty);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public bool deleteFaculty(Faculty faculty)
        {
            bool result = false;
            try
            {
                result = facultyFacade.deleteFaculty(faculty);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        #endregion

        #region Book

        public List<Book> getBooks()
        {
            List<Book> books = bookFacade.getBooks();
            return books;
        }

        public Book getBookById(Guid idBook)
        {
            Book book = bookFacade.getBookById(idBook);
            return book;
        }

        public List<Book> getBooksByIdUser(Guid userId)
        {
            List<Book> books = bookFacade.getBooks().Where(x => x.UserId == userId).ToList();
            return books;
        }

        public bool insertBook(Book book)
        {
            bool result = false;
            try
            {
                result = bookFacade.insertBook(book);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool updateBook(Book book)
        {
            bool result = false;
            try
            {
                result = bookFacade.updateBook(book);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public User getUserByIdBook(Guid bookId)
        {
            Book book = this.getBookById(bookId);
            User owner = this.getUserById(book.UserId);
            return owner;
        }

        public bool deleteBooks(Guid userId)
        {
            bool result = false;
            try
            {
                result = bookFacade.deleteBooks(userId);
            }
            catch (Exception ex)
            {
                result = false;
            }

            return result;
        }

        public bool deleteBook(Guid bookId)
        {
            bool result = false;
            try
            {
                result = bookFacade.deleteBook(bookId);
            }
            catch (Exception ex)
            {
                result = false;
            }

            return result;
        }

        #endregion

        #region Sales

        public List<Sale> getSalesByBookId(Guid bookId)
        {
            List<Sale> sales = saleFacade.getSalesByBookId(bookId);
            return sales;
        }

        public List<Sale> getSalesByUserId(Guid userId)
        {
            List<Sale> sales = saleFacade.getSalesByUserId(userId);
            return sales;
        }

        public Book getBookByIdSale(Guid idSale)
        {
            Sale sale = saleFacade.getSales().Where(x => x.IdSale == idSale).FirstOrDefault();
            return this.getBookById(sale.BookId.Value);
        }

        public List<Sale> getSales()
        {
            List<Sale> sales = saleFacade.getSales();
            return sales;
        }

        public User getUserIdByIdSale(Guid idSale)
        {
            Sale sale = saleFacade.getSales().Where(x => x.IdSale == idSale).FirstOrDefault();
            return this.getUserById(sale.UserIdPurchaser.Value);
        }

        public bool insertSale(Sale sale)
        {
            bool result = false;
            try
            {
                result = saleFacade.insertSale(sale);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool existPreviousRequest(Guid userId, Guid bookId)
        {
            bool result = false;
            try
            {
                result = saleFacade.existPreviousRequest(userId, bookId);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public bool updateSaleStatus(Sale sale, Guid saleStatusId)
        {
            bool result = false;
            try
            {
                result = saleFacade.updateSaleStatus(sale, saleStatusId);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool setEndDate(Sale sale, DateTime endDate)
        {
            bool result = false;
            try
            {
                result = saleFacade.setEndDate(sale, endDate);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public bool updateSale(Sale sale)
        {
            bool result = false;
            try
            {
                result = saleFacade.updateSale(sale);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public bool deleteSales(Guid userId)
        {
            bool result = false;
            try
            {
                result = saleFacade.deleteSales(userId);
            }
            catch (Exception ex)
            {
                result = false;
            }

            return result;
        }

        #endregion

        #region Messages

        public List<Message> getMessagesBetweenSellerPurchaser(Guid sellerId, Guid purchaserId)
        {
            List<Message> messages = messageFacade.getMessagesBetweenSellerPurchaser(sellerId, purchaserId);
            return messages;
        }

        public bool insertMessage(Message message)
        {
            bool result = false;
            try
            {
                result = messageFacade.insertMessage(message);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }

            return result;
        }

        public bool deleteMessages(Guid userId)
        {
            bool result = false;
            try
            {
                result = messageFacade.deleteMessages(userId);
            }
            catch (Exception ex)
            {
                result = false;
            }

            return result;
        }

        #endregion

        #region Users
        public List<User> getUsers()
        {
            List<User> usersList = userFacade.getUsers();
            return usersList;
        }

        public bool CheckExistingRegistration(string email)
        {
            return userFacade.CheckExistingRegistration(email.ToLower());
        }

        public bool UserNameExist(string username)
        {
            return userFacade.UserNameExist(username.ToLower());
        }

        public User getUserByEmailAndPsw(String email, String password)
        {
            User user = userFacade.getUsernameByEmailAndPsw(email, password);
            return user;
        }

        public User getUserByEmail(string email)
        {
            User user = userFacade.getUserByEmail(email);
            return user;
        }

        public User getUserById(Guid idUser)
        {
            User user = userFacade.getUserById(idUser);
            return user;
        }

        public bool insertUser(User user)
        {
            bool result = true;
            try
            {
                userFacade.insertUser(user);
            }
            catch (Exception)
            {
                result = false;
            }
            
            return result;
        }

        public bool modifyUserAccessDate(User user)
        {
            bool result = true;
            try
            {
                userFacade.modifyUserAccessDate(user);
            }
            catch (Exception)
            {
                result = false;
            }

            return result;
        }

        public bool updatePassword(User user)
        {
            bool result = true;
            try
            {
                userFacade.updatePassword(user);
            }
            catch (Exception)
            {
                result = false;
            }

            return result;
        }

        public bool updateUser(User user)
        {
            bool result = false;
            try
            {
                result = userFacade.updateUser(user);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return result;
        }

        public List<User> getUsersByUniversityId(Guid universityId)
        {
            List<User> users = new List<User>();
            try
            {
                 users = userFacade.getUsersByUniversityId(universityId);
            }
            catch (Exception ex)
            {
                throw new ServiceException(ex.Message, ex);
            }
            return users;
        }

        public bool deleteUser(Guid userId)
        {
            bool result = false;
            try
            {
                result = userFacade.deleteUser(userId);
            }
            catch (Exception ex)
            {
                result = false;
            }

            return result;
        }

        #endregion      

        #region RecoveryCode

        public bool insertRecoveryRow(RecoveryCode recovery)
        {
            bool result = true;
            try
            {
                recoveryFacade.insertRecoveryRow(recovery);
            }
            catch (Exception)
            {
                result = false;
            }

            return result;
        }

        public Guid getUserByRecoveryCode(string recoveryCode)
        {
            Guid userId = recoveryFacade.getUserByRecoveryCode(recoveryCode);
            return userId;
        }

        public bool deleteRecoveryCode(Guid userId)
        {
            bool result = false;
            try
            {
                result = recoveryFacade.deleteRecoveryCode(userId);
            }
            catch (Exception ex)
            {
                result = false;
            }

            return result;
        }

        #endregion
    }
}
